﻿using System;
using System.Collections.Generic;
using System.Drawing;

namespace Model
{
	public class Cell
	{
		private CellDefinition cellDefinition;
		public CellDefinition CellDefinition
		{
			get { return cellDefinition; }
			set { cellDefinition = value; OnPropertyChanged(); }
		}

		private Dictionary<string, Attribut> attributes = new Dictionary<string, Attribut>();
		public Dictionary<string, Attribut> Attributes
		{
			get { return attributes; }
			set { attributes = value; }
		}

		private Point position;
		public Point Position
		{
			get { return position; }
			set { position = value; }
		}

		public Cell() { }

		public Cell(Cell cell, Point position)
		{
			this.attributes = new Dictionary<string, Attribut>(cell.attributes);
			this.position = position;
		}

		public Cell(CellDefinition cellDefinition, Point position)
		{
			this.position = position;
			this.cellDefinition = cellDefinition;
			foreach (var attribute in cellDefinition.Attributes)
			{
				this.attributes.Add(attribute.Key, attribute.Value.Copy());
			}
		}

		#region ChangeCell

		private CellDefinition cellDefTarget;
		private Dictionary<string, AttributExpression> attributExpressions = new Dictionary<string, AttributExpression>();

		public void ChangeCellDefinition()
		{
			Change(cellDefTarget);
		}

		public void SetCellDefinitionTarget(CauseExpression causeExpr)
		{
			cellDefTarget = causeExpr.CellDefinition;
			this.attributExpressions = causeExpr.AttributeExpressions;
		}

		private void Change(CellDefinition cellDef)
		{
			if (cellDef != null)
			{
				if (cellDef.Equals(this.cellDefinition))
				{
					foreach (var tmpAttrExpr in attributExpressions)
					{
						if (attributes.ContainsKey(tmpAttrExpr.Key))
						{
							Attribut a = attributes[tmpAttrExpr.Key];
							tmpAttrExpr.Value.EvaluateExpression(ref a);
						}
					}
					attributExpressions = new Dictionary<string, AttributExpression>();
				}
				else
				{
					attributes = new Dictionary<string, Attribut>();
					foreach (Attribut tmpAttr in cellDef.Attributes.Values)
					{
						this.attributes.Add(tmpAttr.Name, tmpAttr.Copy());
					}
				}
				cellDefinition = cellDef;
			}
		}

		public void GUISetCellDefinition(Model.CellDefinition cellDef)
		{
			cellDefTarget = cellDef;
			Change(cellDef);
			OnPropertyChanged();
		}

		#endregion

		public override string ToString()
		{
			return cellDefinition.Name;
		}

		#region PropertyChanged
		public delegate void PropertyChangedEventHandler(object sender, EventArgs e);

		public event PropertyChangedEventHandler PropertyChanged;

		protected void OnPropertyChanged()
		{
			if (PropertyChanged != null)
			{
				EventArgs args = new EventArgs();
				PropertyChanged(this, args);
			}
		}
		#endregion

	}
}
